﻿/*
Javascript Extensions
====================

Version: 1.0

Requisites: <none>

Features: add common methods to JavaScript internal objects like `String`, `Date`...

Usage:

'string'.startsWith(text)
'string'.format(params)
'string'.contains(text)
'string'.trim()
'string'.ltrim()
'string'.rtrim()

date.format(format)
*/
function isNumber(n) {
    return !isNaN(parseFloat(n)) && isFinite(n);
}

String.prototype.startsWith = function (text) {
    return this.indexOf(text) == 0;
};

String.prototype.format = function () {
    var value = this;
    for (var i = 0; i < arguments.length; i++) {
        value = value.replace('{' + i + '}', arguments[i]);
    }
    return value;
};

String.prototype.contains = function (text) {
    return this.indexOf(text) >= 0;
};

String.prototype.trim = function () {
    return this.replace(/^\s+|\s+$/g, '');
}
String.prototype.ltrim = function () {
    return this.replace(/^\s+/, '');
}
String.prototype.rtrim = function () {
    return this.replace(/\s+$/, '');
}

/* Date */
Date.prototype.format = function (format) {
    return format.replace('yyyy', this.getFullYear())
        .replace('MM', this.getMonth() + 1)
        .replace('dd', this.getDate())
        .replace('HH', this.getHours())
        .replace('mm', this.getMinutes())
        .replace('ss', this.getSeconds());
};

$.fn.outerBound = function () {
    var pos = this.offset();
    var rect = this.outerRect();

    return {
        left: pos.left,
        top: pos.top,
        width: rect.width,
        height: rect.height
    };
};
$.fn.innerBound = function () {
    var pos = this.offset();
    var rect = this.innerRect();

    if (!isNumber(pos.left) || !isNumber(pos.top)) {
        pos = { left: 0, top: 0 }
    }

    return {
        left: pos.left + rect.left,
        top: pos.top + rect.top,
        width: rect.width,
        height: rect.height
    };
};
$.fn.outerRect = function () {
    return {
        left: 0,
        top: 0,
        width: this.outerWidth(),
        height: this.outerHeight()
    };
};
$.fn.innerRect = function () {
    var left = 0;
    var top = 0;
    if (this.css('padding-left')) {
        left = this.css('padding-left').replace('px', '') * 1;
    }
    if (this.css('padding-top')) {
        top = this.css('padding-top').replace('px', '') * 1;
    }

    return {
        left: left,
        top: top,
        width: this.width(),
        height: this.height()
    };
};
$.fn.hasAttr = function (name) {
    return this.attr(name) !== undefined && this.attr(name) !== false;
};
$.fn.hasParent = function (objs) {
    var found = false;
    $(this[0]).parents().andSelf().each(function () {
        if (this == objs[0]) {
            found = true;
            return false;
        }
    });
    return found;
}

/* Knockout.js */

ko.fromKo = function (data) {
    for (var key in data) {
        var type = typeof data[key];

    }
};
ko.update = function (target, data) {
    for (var key in data) {
        if (typeof target[key] === 'undefined') {
            continue;
        }
        target[key](data[key]);
    }
};
ko.serialize = function (data) {
    var obj = {};
    for (var key in data) {
        obj[key] = data[key]();
    }
    return obj;
}